RFC 7591
概要
OAuth 2.0 Dynamic Client Registration Protocol
OAuthで認可を求めるクライアントに対して自動的にclient_idを発行する方法。
そのクライアントを認可サーバが信用するかしないかを決める方法はRFC 7591の範囲外。
ただしクライアントが自分に関する情報(Software Statement)を署名付きで提示する方法は定められている。
クライアントが自身の公開鍵を提示する方法も定められている。
信じるか信じないかは認可サーバ次第。
https://scrapbox.io/files/601cc153837fd4002256c273.png
クライアントをどうやって信用するか
クラアントから提示された各種のメタデータを見て頑張って推測するしかないが、どうやって信用するかはRFC 7591の範囲外。
software_statementの使用は必須ではないが、これにつけられた電子的な署名に頼るしかないのではないか。
クライアントとの間で事前に共有された共通鍵があるならJWTのHS256で。
クライアントの公開鍵を信頼する方法がわかっているならJWTのRS256で。
公開鍵をTLSで保護された場所においてjwks_uriで示せば、X.509の仕組みで信頼できる。
ネイティブアプリの場合は事前に共有された共通鍵を信頼できない。
これは基本的なOAuth2で使われるclient_secretがクライアント側で安全に保管できるとは確信できないのと同じ。
クライアントからjwksで提示された公開鍵を信頼するかは、結局のところGnuPGやPGPのような信頼の連鎖によるしかない。
TLSで保護されたサーバにネイティブアプリの公開鍵を登録してjwks_uriで示す場合はX.509の仕組みで信頼することになる。
結局のところX.509 vs GnuPGである。
関連規格
OpenID Connect Dynamic Client Registration 1.0
User Managed Access (UMA) Profile of OAuth 2.0
JSON Web Token (JWT)
Client metadata
認可サーバは登録したクライアントにclient_idを発行するとともに、そのクライアントに関する情報を保持する。
Client metadataはクライアントが認可サーバに登録する際のリクエストのbodyにJSONで含めることもできるし、Software Statementにバンドルすることもできる。
同じ名前のメタデータが両方に出現した場合はSoftware Statementのほうを優先する。
Software Statementは署名付きのJWTなので。
redirect_uris
tokenendpoint_auth_method
none
client_secret_post
client_secret_basic
デフォルトはこれ
その他もあり
IANAのOAuth Token Endpoint Authentication Methodsに登録されている
grant_type
authorization_code
implicit
password
client_credentials
refresh_token
urn:ietf:params:oauth:grant-type:jwt-bearer
urn:ietf:params:oauth:grant-type:saml2-bearer
response_types
code
token
client_name
クライアントの人間が読める名前。多言語化に対応するための方法も定義されている。
省略されると認可サーバはclient_idを生のまま表示する
client_uri
クライアントについての説明が記載されているURL
これがあるとき認可サーバはユーザーがクリックできる状態で提示しなければならない
logo_url
scope
contacts
tos_uri
policy_uri
jwks_uri
クライアントのJWK (JWK) Set RFC 7517
クライアントの公開鍵を含む
署名と暗号化に使われる
jwkと同時にはリクエストやレスポンスに含められない
jwks
クライアントがネイティブアプリケーションだとpublic URLは無いのでjwks_uriの代わりに。
software_id
ソフトウェアを識別するためのUUIDなどの一意な文字列
同じソフトウェアの異なるインスタンスには認可サーバから異なるclient_idが与えられるが、software_idは共通。
バージョンが変わってもsoftware_idは変わってはいけない。
software_version
Software Statement
クライアントの秘密鍵によって署名されるかMACで検証可能なJWT(JSON Web Token)。
Client metadataがバンドルされている。
認可サーバがクライアントの登録を受け付けるかどうかの判断に使う。
JWT
JWSに沿ってdigitally signed or MACed
issを含む
Software Statementがどのようにして入手できるかについてはRFC 7591の範疇外
Software Statementに含まれる情報を同信用するかについてはRFC 7591の範疇外
code:Software Statementの例.json
{
"software_id": "4NRB1-0XZABZI9E6-5SM3R",
"client_name": "Example Statement-based Client",
"client_uri": "https://client.example.net/"
}
Client Registration Endpoint
POSTメソッドを使う
applicatin/json
initial access tokenで守ってもよいが、initial access tokenをどのようにしてクライアントが得るかについてはRFC 7591の範疇外。
DoS攻撃に注意
登録リクエストの例
Software Statementを使わない登録リクエストの例
クライアントはjwksで公開鍵を提示している。
ベアラトークンでinitial access tokenを提示している。
code:Software Statementを使わない登録リクエストの例.json
POST /register HTTP/1.1
Content-Type: application/json
Accept: application/json
Authorization: Bearer ey23f2.adfj230.af32-developer321
Host: server.example.com
{
"redirect_uris": ["https://client.example.org/callback",
"https://client.example.org/callback2"],
"client_name": "My Example Client",
"client_name#ja-Jpan-JP":
"\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8\u540D",
"token_endpoint_auth_method": "client_secret_basic",
"policy_uri": "https://client.example.org/policy.html",
"jwks": {"keys": [{
"e": "AQAB",
"n": "nj3YJwsLUFl9BmpAbkOswCNVx17Eh9wMO-_AReZwBqfaWFcfGHrZXsIV2VMCNVNU8Tpb4obUaSXcRcQ-VMsfQPJm9IzgtRdAY8NN8Xb7PEcYyklBjvTtuPbpzIaqyiUepzUXNDFuAOOkrIol3WmflPUUgMKULBN0EUd1fpOD70pRM0rlp_gg_WNUKoW1V-3keYUJoXH9NztEDm_D2MQXj9eGOJJ8yPgGL8PAZMLe2R7jb9TxOCPDED7tY_TU4nFPlxptw59A42mldEmViXsKQt60s1SLboazxFKveqXC_jpLUt22OC6GUG63p-REw-ZOr3r845z50wMuzifQrMI9bQ",
"kty": "RSA"
}]},
"example_extension_parameter": "example_value"
}
Software Statementを使った登録リクエストの例
クライアントはsoftware_statementでSoftware Statementを提示している。
JWTはRS256で署名されている。
code:Software Statementを使ったリクエストの例.json
POST /register HTTP/1.1
Content-Type: application/json
Accept: application/json
Host: server.example.com
{
"redirect_uris": [
"https://client.example.org/callback",
"https://client.example.org/callback2"
],
"software_statement": "eyJhbGciOiJSUzI1NiJ9.eyJzb2Z0d2FyZV9pZCI6IjROUkIxLTBYWkFCWkk5RTYtNVNNM1IiLCJjbGllbnRfbmFtZSI6IkV4YW1wbGUgU3RhdGVtZW50LWJhc2VkIENsaWVudCIsImNsaWVudF91cmkiOiJodHRwczovL2NsaWVudC5leGFtcGxlLm5ldC8ifQ.GHfL4QNIrQwL18BSRdE595T9jbzqa06R9BT8w409x9oIcKaZo_mt15riEXHazdISUvDIZhtiyNrSHQ8K4TvqWxH6uJgcmoodZdPwmWRIEYbQDLqPNxREtYn05X3AR7ia4FRjQ2ojZjk5fJqJdQ-JcfxyhK-P8BAWBd6I2LLA77IG32xtbhxYfHX7VhuU5ProJO8uvu3Ayv4XRhLZJY4yKfmyjiiKiPNe-Ia4SMy_d_QSWxskU5XIQl5Sa2YRPMbDRXttm2TfnZM1xx70DoYi8g6czz-CPGRi4SW_S2RKHIJfIjoI3zTJ0Y2oe0_EJAiXbL6OyF9S5tKxDXV8JIndSA",
"scope": "read write",
"example_extension_parameter": "example_value"
}
code:JWTのヘッダ.json
{"alg":"RS256"}
code:JWTのペイロード.json
{"software_id":"4NRB1-0XZABZI9E6-5SM3R","client_name":"Example Statement-based Client","client_uri":"https://client.example.net/"}
jwks_uriを使った登録リクエストの例
code:jwks_uriを使った登録リクエストの例.json
POST /register HTTP/1.1
Content-Type: application/json
Accept: application/json
Host: server.example.com
{
"redirect_uris": [
"https://client.example.org/callback",
"https://client.example.org/callback2"],
"client_name": "My Example Client",
"client_name#ja-Jpan-JP":
"\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8\u540D",
"token_endpoint_auth_method": "client_secret_basic",
"logo_uri": "https://client.example.org/logo.png",
"jwks_uri": "https://client.example.org/my_public_keys.jwks",
"example_extension_parameter": "example_value"
}